package service;

import com.thoughtworks.xstream.XStream;
import entity.*;
import net.sf.json.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import util.Util;


import javax.net.ssl.HttpsURLConnection;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * Created by Administrator on 2019/1/21.
 */
public class WxService {
    private  static final String TOKEN = "ljm";
    private  static final String APPKEY = "1fec136dbd19f44743803f89bd55ca62";
    private static final String GET_TOKENURL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET\n";
    private static final String APPID = "wx66bd1e7b808b8ac6";
    private static final String APPSECRET = "75a3e7c0a8bc8a583b122a97e801b88f";

    //用于存储token
    private static AccessToken at;

    //获取token
    public static void getToken(){
        String url = GET_TOKENURL.replace("APPID",APPID).replace("APPSECRET",APPSECRET);
        String tokenStr = Util.get(url);
        System.out.println(tokenStr);
       JSONObject jsonObject= JSONObject.fromObject(tokenStr);
       String token =  jsonObject.getString("access_token");
       String expireIn = jsonObject.getString("expires_in");
       //创建token对象，并存起来
       at = new AccessToken(token,expireIn);
    }

    public static String getAccessToken(){
        if (at==null||at.isExpired()){
            getToken();
        }
        return at.getAccessToken();
    }


    public static boolean check (String signature, String timestamp, String nonce){
        // 对token、timestamp、和nonce按字典排序.
        String[] paramArr = new String[] {TOKEN, timestamp, nonce};
        Arrays.sort(paramArr);

        // 将排序后的结果拼接成一个字符串.
        String content  = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);

        String ciphertext = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            // 对拼接后的字符串进行sha1加密.
            byte[] digest = md.digest(content.toString().getBytes());
            ciphertext = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        // 将sha1加密后的字符串与signature进行对比.
        return ciphertext != null ? ciphertext.equals(signature.toUpperCase()) : false;
    }
    /**
     * 将字节数组转换为十六进制字符串.
     * @param byteArray
     * @return
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }

    /**
     * 将字节转换为十六进制字符串.
     * @param mByte
     * @return
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = { '0', '1' , '2', '3', '4' , '5', '6', '7' , '8', '9', 'A' , 'B', 'C', 'D' , 'E', 'F'};
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];
        String s = new String(tempArr);
        return s;
    }


    public static Map<String,String> parseRequest(InputStream ins) {
        Map<String, String> map = new HashMap<String, String>();
        SAXReader reader = new SAXReader();

       try {
           Document document = reader.read(ins);
           Element root = document.getRootElement();
           List<Element> elements = root.elements();
           for (Element e:elements){
               map.put(e.getName(),e.getStringValue());
           }
       }catch (DocumentException e){
           e.printStackTrace();
       }
        return map;
    }


    //用于处理所有事件和消息的回复   返回的是一个xml数据包
    public static String getResponse(Map<String, String> requestMap) {
        BaseMessage msg=null;
        String msgType = requestMap.get("MsgType");
        String content = requestMap.get("Content");
        switch (msgType){
            //处理文本消息
            case"text":
//                dealText(requestMap);
                msg = dealTextMessage(requestMap);
                break;
            case"image":
                msg = dealImageMessage(requestMap);
                break;
            case"voice":

                break;
            case"video":

                break;
            case"shortvideo":

                break;
            case"location":

                break;
            case"link":

                break;
            case"event":
                msg = dealEvent(requestMap);

                break;
            default:
                break;
        }
        if(msg!=null){
            return beanToXml(msg);
        }
        return null;
    }

    private static BaseMessage dealEvent(Map<String, String> requestMap) {
    
        String event = requestMap.get("Event");
        switch (event){
            case "CLICK":
                return dealClick(requestMap);
            case "VIEW":
                return dealView(requestMap);
            default:
                break;   
        }
        return null;
    }

    private static BaseMessage dealView(Map<String, String> requestMap) {

        return null;
    }

    private static BaseMessage dealClick(Map<String, String> requestMap) {
        String key = requestMap.get("EventKey");
        switch (key){
                case "1":
                    //处理点击第一个一级菜单
                    return  new TextMessage(requestMap,"我是一级菜单");
                case "32":
                    //处理点击第3个一级菜单的第二个子菜单
                    List<Article> articles = new ArrayList<>();
                    articles.add(new Article("这是一个图文","图文呀","http://mmbiz.qpic.cn/mmbiz_jpg/icS6MgficzGNgHdTlVcgtoZlia49xIiaQ00HfFGmQs9ib9QOQCoGdP0ZELjJs3GIKTEWhvPZxEbq36DgUGNIFJ9DzgA/0","http://www.baidu.com"));
                    NewMessage nm= new NewMessage(requestMap,articles);
                    return nm;
                default:
                    break;
        }
        return null;
    }

    //把数据处理为xml数据包
    private static String beanToXml(BaseMessage msg) {
        XStream stream = new XStream();
        //把形势换成xml开头结尾
        stream.processAnnotations(TextMessage.class);
        stream.processAnnotations(ImageMessage.class);
        stream.processAnnotations(MusicMessage.class);
        stream.processAnnotations(VoiceMessage.class);
        stream.processAnnotations(NewMessage.class);
        stream.processAnnotations(VideoMessage.class);
        String xml = stream.toXML(msg);
        return xml;
    }

    private static BaseMessage dealImageMessage(Map<String, String> requestMap) {

//        ImageMessage im = new ImageMessage(requestMapd,);

        return null;


    }

    private static BaseMessage dealTextMessage(Map<String, String> requestMap) {
        String msg = requestMap.get("Content");
        if(msg.equals("图文")){
            List<Article> articles = new ArrayList<>();
            articles.add(new Article("这是一个图文","图文呀","http://mmbiz.qpic.cn/mmbiz_jpg/icS6MgficzGNhAmwMaIxCEr44XlrGPHX2wsoQ3va80ibmcJxria37Jviad4XqDS8yiakUUuPDQrP8mcSk2YQWv9lXGiaw/0","http://www.baidu.com"));
            NewMessage nm= new NewMessage(requestMap,articles);
            System.out.println(nm);

            return nm;
        }
        String resp = chat(msg);
        TextMessage tm = new TextMessage(requestMap,resp);
        return tm;
    }

    //调用图灵机器人聊天
    private static String chat(String msg) {

            String result =null;
            String url ="http://op.juhe.cn/robot/index";//请求接口地址
            Map params = new HashMap();//请求参数
            params.put("key",APPKEY);//您申请到的本接口专用的APPKEY
            params.put("info",msg);//要发送给机器人的内容，不要超过30个字符
            params.put("dtype","");//返回的数据的格式，json或xml，默认为json
            params.put("loc","");//地点，如北京中关村
            params.put("lon","");//经度，东经116.234632（小数点后保留6位），需要写为116234632
            params.put("lat","");//纬度，北纬40.234632（小数点后保留6位），需要写为40234632
            params.put("userid","");//1~32位，此userid针对您自己的每一个用户，用于上下文的关联

            try {
                result = Util.net(url, params, "GET");
                //解析json
                JSONObject jsonObject = JSONObject.fromObject(result);
                //取出error code
                int code = jsonObject.getInt("error_code");
                if(code!=0){
                    return null;
                }
                String resp1 = jsonObject.getJSONObject("result").getString("text");

                System.out.println(result);
                return resp1;

            } catch (Exception e) {
                e.printStackTrace();
            }
        return null;
    }



    //上传临时素材  path 路径    type 类型
    public static String upLoad(String path,String type){

        File file = new File(path);
        String url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
        url = url.replace("ACCESS_TOKEN",getAccessToken()).replace("TYPE",type);

        System.out.println(getAccessToken());
        try {
            URL urlObject = new URL(url);
            HttpsURLConnection connection =(HttpsURLConnection) urlObject.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);

            //设置请求头信息
            connection.setRequestProperty("Connection","Keep-Alive");
            connection.setRequestProperty("Charset","utd8");
            //数据的边界

            String boundary = "______"+System.currentTimeMillis();
            connection.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary);

            //获取输出流
            OutputStream out =  connection.getOutputStream();
            //创建文件的输入流
            InputStream is = new FileInputStream(file);
            //第一部分 ： 头部信息
            //准备头部信息
            StringBuilder sb = new StringBuilder();
            sb.append("--");
            sb.append(boundary);
            sb.append("\r\n");
            sb.append("Content-Disposition:form-data;name=\"media\";filename=\""+file.getName()+"\"\r\n");
            sb.append("Content-Type:application/octet-stream\r\n\r\n");

            out.write(sb.toString().getBytes());

            //第二部分 ： 文件内容
            byte[] b =new byte[1024];
            int len;
            while ((len=is.read(b))!=-1){
                out.write(b,0,len);
            }

            //第三部分  ： 尾部信息

            String foot = "\r\n--"+boundary+"--\r\n";
            out.write(foot.getBytes());
            out.flush();
            out.close();

            InputStream is2 = connection.getInputStream();
            StringBuilder resp = new StringBuilder();
            while ((len=is2.read(b))!=-1){
                resp.append(new String(b,0,len));
            }
            return resp.toString();

        }catch (Exception e){
            e.printStackTrace();
        }
        return  null;
    }


    public static String getCodeTicket(){
        String tk =getAccessToken();
        String url ="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+tk;

        String data = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"刘家明\"}}}";
        String result = Util.post(url,data);
        String ticket = JSONObject.fromObject(result).getString("ticket");


        return ticket;
    }

    //获取用户的基本信息
    public static String getUserInfo(String openId){
        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
        url = url.replace("ACCESS_TOKEN",getAccessToken()).replace("OPENID",openId);

        String result = Util.get(url);

        return result;
    }
}
